-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updated LRO guidelines #517
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left some suggestions to fix minor issues, but I have a larger concern. It looks like this PR has dropped many of the prior guidelines we had in place for LROs. A quick check on the href tags shows all the following guidelines were dropped.
< #lro-no-post-create
< #lro-operation-id-default-is-guid
< #lro-operation-id-request-header
< #lro-operation-id-unique-except-retries
< #lro-put-operation-id-default-is-guid
< #lro-put-operation-id-request-header
< #lro-put-operation-id-unique-except-retries
< #lro-put-operation-location-includes-api-version
< #lro-put-returns-200-or-201
< #lro-put-returns-operation-id-header
< #lro-put-returns-operation-location
< #lro-put-valid-inputs-synchronously
< #lro-returns-202
< #lro-returns-only-202
< #lro-returns-status-monitor
< #lro-status-monitor-accepts-any-api-version
< #lro-status-monitor-get-returns-200
< #lro-status-monitor-includes-all-fields
< #lro-status-monitor-no-resource-result
< #lro-status-monitor-post-action-result
< #lro-status-monitor-retry-after
< #lro-status-monitor-structure
This has me concerned that the PR is a "more revolutionary than evolutionary" change to our LRO guidelines, which is not what I had understood from your word doc.
Maybe the guidelines above are retained but just their tags were lost?
Or is this a more wholesale change?
azure/Guidelines.md
Outdated
The second pattern applies only in the case of a PUT operation to create a resource that also involves additional long-running processing. | ||
For guidance on when to use a specific pattern, please refer to [Considerations for Service Design, Long Running Operations](./ConsiderationsForServiceDesign.md#long-running-operations). | ||
These are described in the following two sections. | ||
## Patterns to Initiate a Long-Running Operation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Patterns to Initiate a Long-Running Operation | |
#### Patterns to Initiate a Long-Running Operation |
azure/Guidelines.md
Outdated
|
||
**OperationStatus** : Object | ||
## The Status Monitor Resource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## The Status Monitor Resource | |
#### The Status Monitor Resource |
azure/Guidelines.md
Outdated
|
||
<a href="#lro-status-monitor-includes-all-fields" name="lro-status-monitor-includes-all-fields">:white_check_mark:</a> **DO** include the `id` of the operation and any other values needed for the client to form a GET request to the status monitor (e.g. a `location` path parameter). | ||
## Pattern to Poll a Long-Running Operation's Status |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Pattern to Poll a Long-Running Operation's Status | |
#### Pattern to Poll a Long-Running Operation's Status |
azure/Guidelines.md
Outdated
|
||
<a href="#lro-status-monitor-retention" name="lro-status-monitor-retention">:white_check_mark:</a> **DO** retain the status monitor resource for some publicly documented period of time (at least 24 hours) after the operation completes. | ||
|
||
## Pattern to List Status Monitors (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Pattern to List Status Monitors (optional) | |
#### Pattern to List Status Monitors (optional) |
@mikekistler, I want to address this comment: #517 (review) This is a wholesale rewrite of the guideline text but all the old guidelines remain. I struggled without how to get the guidelines across in a simplified manner. I untimately settled on what worked during our discussions with my Word document. That is, the HTTP requests/responses themselves in the new guidelines SHOW exactly what to do as opposed to explaining via text what to do. I think this makes it easier to follow and is more prescriptive for service teams. If you pick some text guideline that was there before and read the new guidelines, I'm very sure you'll find the issue still covered but by way of prescriptive example. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a lot of formatting inconsistencies that will make a difference, but I'm mostly concerned about switching to a single directive (that we can right-click and copy the link to send in reviews, PR reviews, etc.) with a lot of bullet points beneath. That's not how we've written these guidelines previously. Even though it might make sense to group them that way, I think the bullets should still have the DOs and SHOULDs and all that, along with bookmarks.
Where possible, we should try to retain existing bookmarks - even if we create new ones (just use the <a name>
in that case) because we have been linking these out in reviews.
By no means am I suggesting we shouldn't drop things when it makes sense - I'm 100% behind updating guidelines as we learn better patterns or need to clarify - but let's try to keep this stable like we would any REST API. These guidelines are also living contract like swaggers.
azure/Guidelines.md
Outdated
through another API call. | ||
See the [Long Running Operations section](./ConsiderationsForServiceDesign.md#long-running-operations) in | ||
Considerations for Service Design for an introduction to the design of long-running operations. | ||
A _long-running operation (LRO)_ is typically an operation that should execute synchronously but due to services not wanting to maintain long-lived connections (>1 seconds) and load-balancer timeouts the operation must execute asynchronously. For this pattern, the client initiates the operation on the service and then the client repeatedly polls the service (via another API call) to track the operation's progress/completion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is typically an operation that should execute synchronously
A lot of the LROs we've reviewed don't fall into this, and it seems the norm - especially for very LROs like cert signing, AI tagging, etc. - is quickly growing to truly LROs. I think this assertion is misleading and could make people doubt whether they should be using an LRO or not. The original text seemed fine.
azure/Guidelines.md
Outdated
|
||
<a href="#lro-valid-inputs-synchronously" name="lro-valid-inputs-synchronously">:white_check_mark:</a> **DO** perform as much validation as practical when initiating the operation to alert clients of errors early. | ||
- The resource schema must contain an `initializationStatus` property indicating whether the initialization is `Running`, `Failed`, `Succeeded`, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not crazy about "etc". We document the supported / recommended values. Either list them here, or link to them (I believe they are above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is the same PUT to create a resource (as we support today).
On the initializationStatus
property: so we got another "required" property that would only exist in future LRO, but not in existing LRO?
Trying to see if we can avoid the nuance of "legacy LRO", "LRO without initializationStatus", "LRO with initializationStatus and kind"...
azure/Guidelines.md
Outdated
@@ -1098,8 +1180,65 @@ While it may be tempting to use a revision/version number for the resource as th | |||
|
|||
<a href="#condreq-etag-depends-on-encoding" name="condreq-etag-depends-on-encoding">:white_check_mark:</a> **DO**, when supporting multiple representations (e.g. Content-Encodings) for the same resource, generate different ETag values for the different representations. | |||
|
|||
<a href="#substrings" name="substrings"></a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, for headers this is pointless. It's not what commonmark will use during rendering, which is what GitHub et. al. use.
azure/Guidelines.md
Outdated
|
||
For example, if a service response needed to identify offset & length values for "name" and "email" substrings, the JSON response would look like this: | ||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
``` | |
```json |
Will properly syntax highlight it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...though, I'd then elide line 1201 below since it won't be valid and their json
highlighter doesn't like comments. You might see if jsonc
works.
azure/Guidelines.md
Outdated
``` | ||
{ | ||
(... other properties not shown...) | ||
"fullString": "(...some string containing a name and an email address...)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we actually include a working example with emoji or international characters so people perhaps get a better sense of when simple indexes or lengths fail?
azure/Guidelines.md
Outdated
``` | ||
var response := client.SomeMethodReturningJSONShownAbove(...) | ||
name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8] | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well show proper syntax highlighting (and code):
``` | |
var response := client.SomeMethodReturningJSONShownAbove(...) | |
name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8] | |
``` | |
```go | |
response := client.SomeMethodReturningJSONShownAbove("...") | |
name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8] | |
``` |
azure/Guidelines.md
Outdated
name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8] | ||
``` | ||
|
||
The service must calculate the offset & length for all 3 encodings and return them because clients find it difficult working with Unicode encodings and how to convert from one encoding to another. In other words, we do this to simplify client development and ensure customer success when isolating a substring. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize we've already discussed this, but I find this statement contradictory. It is a hard problem, but why is them passing the encoding any different than them knowing which encoding to use coming back in the response?
I still think this is something that our 1P clients - generated or otherwise - should handle for them. It could still be the same response - I know that helps solve problems of calling into one service that calls another service - but we can still make it easy by helping select - or just do it for them - the right encoding for the language SDK being used.
azure/Guidelines.md
Outdated
|
||
<a href="#lro-valid-inputs-synchronously" name="lro-valid-inputs-synchronously">:white_check_mark:</a> **DO** perform as much validation as practical when initiating the operation to alert clients of errors early. | ||
- The resource schema must contain an `initializationStatus` property indicating whether the initialization is `Running`, `Failed`, `Succeeded`, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is the same PUT to create a resource (as we support today).
On the initializationStatus
property: so we got another "required" property that would only exist in future LRO, but not in existing LRO?
Trying to see if we can avoid the nuance of "legacy LRO", "LRO without initializationStatus", "LRO with initializationStatus and kind"...
azure/Guidelines.md
Outdated
|
||
For a PUT (create or replace) with additional long-running processing: | ||
- Do not return a response body. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the resource disappear right now (after the DELETE), or it still there and only disappear after LRO success? If latter, how's it initializationStatus
(or other state) if queried via GET?
@markcowl @allenjzhang For your awareness. Once these guidelines are finalized we should add support in TypeSpec for the new patterns. |
A comment on I don't think we should add the |
Co-authored-by: Jeffrey Richter <jeffreyr@microsoft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments
|
||
<a href="#lro-put-valid-inputs-synchronously" name="lro-put-valid-inputs-synchronously">:white_check_mark:</a> **DO** perform as much validation as practical when initiating the operation to alert clients of errors early. | ||
|
||
<a href="#lro-put-returns-200-or-201" name="lro-put-returns-200-or-201">:white_check_mark:</a> **DO** return a `201-Created` status code for create or `200-OK` for replace from the initial request with a representation of the resource if the resource was created successfully. | ||
|
||
<a href="#lro-put-returns-operation-id-header" name="lro-put-returns-operation-id-header">:white_check_mark:</a> **DO** include an `Operation-Id` header in the response with the ID of the status monitor for the operation. | ||
|
||
<a href="#lro-put-response-headers" name="lro-put-response-headers">:white_check_mark:</a> **DO** include response headers with any additional values needed for a GET request to the status monitor (e.g. location). | ||
|
||
<a href="#lro-put-returns-operation-location" name="lro-put-returns-operation-location">:ballot_box_with_check:</a> **YOU SHOULD** include an `Operation-Location` header in the response with the absolute URL of the status monitor for the operation. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about other edge cases such as expired and auto-deleted status monitor case.
that contains a representation of the status monitor _and_ any information from the request used to initiate the operation. | ||
|
||
The service is responsible for purging the status monitor after some period of time. | ||
It should auto-purge this resource after completion (at least 24 hours). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, this sentence may need rephase.
Maybe "This status monitor resource should be retained for at least 24 hours after completion. The service should auto-purge it afterward."
|
||
<a href="#lro-operation-id-request-header" name="lro-operation-id-request-header">:white_check_mark:</a> **DO** allow the client to pass an `Operation-Id` header with an ID for the operation's status monitor. | ||
<a href="#lro-put-response-headers" name="lro-put-response-headers">:white_check_mark:</a> **DO** include response headers with any additional values needed for a [GET polling request](#lro-poll) to the status monitor (e.g. location). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line is moved here without change.
However, it is hard for me to understand the example:
include response headers with any additional values needed for a GET polling request to the status monitor (e.g. location).
I take the "e.g. location" mean the location
header. But a location
header seems not mean much to the GET polling request. (the polling URL should be from operation-location
header that covered in the sentence above.
Do we have a better example? retry-after
header is also mentioned in later point. operation-id
header?
If no good example, maybe skip the example part of the sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the example is poorly explained. The idea is that values passed in headers can be used as parameters -- specifically path parameters -- to the status monitor endpoint. There will always be an operation-id
-- the final path segment -- but there may be other path parameters and headers can be used to specify what values should be used for these.
I don't know that we should go into all that detail in the guidelines doc, but perhaps we should include this in the ConsiderationsForServiceDesign.
Thanks @weidongxu-microsoft for all the great suggestions! Co-authored-by: Weidong Xu <weidxu@microsoft.com>
No description provided.